package com.wtwd.campus.attendancenetty;


import com.wtwd.campus.common.Constants;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * 消息解码
 */
public class MessageDecoder extends ByteToMessageDecoder {
    private static final String cmdArr="A4,A3,A2,A7";

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,
                          List<Object> out) throws Exception {
        // 可读长度必须大于基本长度
        if (buffer.readableBytes() >= 4) {
            if (buffer.readableBytes() > 2048) {    // 防止socket字节流攻击;防止，客户端传来的数据过大;因为，太大的数据，是不合理的
                buffer.skipBytes(buffer.readableBytes());
            }
            int beginReader=0;  // 包头开始的位置
            while (true){
                beginReader=buffer.readerIndex();
                //读取一个字节的长度
                String readString = readData(buffer, 2);
                if(readString.equals("5A")){
                    //找到了开头
                    break;
                }
                // 当剩下的长度不足一包时，应该return;放弃本次读的操作，等待下一包的到来
                if (buffer.readableBytes() < 12) {
                    return;
                }
            }
            //找到了开头，读取数据区域的长度
            buffer.readerIndex(beginReader);
            String firstStr = readData(buffer, 8);
            String dataLenStr = firstStr.substring(4, 8);
            int dataLength = convertToInt(dataLenStr)*2;
            //从计算出来的指令结尾处，看是否能拿到CA
            int length=2+2+4+dataLength+2+2;
            if(length>buffer.readableBytes()+8){
                //理论长度不足则直接返回，等待下一包的到来
                return;
            }
            String command = firstStr.concat(readData(buffer, length-8));
            if("CA".equals(command.substring(command.length()-2,command.length()))){
                //如果符合理论长度，再判断cmd位置的指令标识是否合理
                if(cmdArr.contains(command.substring(2,4))){
                    out.add(command);
                }
            }
        }
    }

    public String readData(ByteBuf buffer,int length) throws UnsupportedEncodingException {
        byte[] data = new byte[length];
        buffer.readBytes(data);
        String hexStringData = new String(data, Constants.DEVICE_DATA_CHARSET);
        return hexStringData;
    }

    public static String byte2HexStr(byte buf[]) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10)
                strbuf.append("0");
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strbuf.toString();
    }



    /**
     * 把十六进制转成二进制
     */
    public  int convertToInt(String str){
        char[] chars = str.toCharArray();
        return (int) (Math.pow(16,3)*(Integer.valueOf(String.valueOf(chars[0])))+Math.pow(16,2)*(Integer.valueOf(String.valueOf(chars[1])))+Math.pow(16,1)*(Integer.valueOf(String.valueOf(chars[2])))+Math.pow(16,0)*(Integer.valueOf(String.valueOf(chars[3]))));
    }


}
